Core: Use exsolve resolveModulePath for safeResolveModule#32477
Conversation
|
View your CI Pipeline Execution ↗ for commit 321d812
☁️ Nx Cloud last updated this comment at |
WalkthroughThis change set standardizes module path resolution across several packages and docs by:
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as Caller (config/migration)
participant GAP as getAbsolutePath
participant IMR as import.meta.resolve
participant URL as fileURLToPath
participant NP as dirname
User->>GAP: getAbsolutePath(value)
Note right of GAP: Build specifier `${value}/package.json`
GAP->>IMR: resolve(specifier)
IMR-->>GAP: file: URL to package.json
GAP->>URL: fileURLToPath(URL)
URL-->>GAP: /abs/path/to/package.json
GAP->>NP: dirname(/abs/path/to/package.json)
NP-->>GAP: /abs/path
GAP-->>User: /abs/path
sequenceDiagram
autonumber
actor SB as Call Site
participant UM as utils/module.ts
participant RMP as resolveModulePath (exsolve)
participant FS as fs
SB->>UM: resolveModulePathLike(parent, request, extensions)
UM->>RMP: resolve({ from: parent, extensions: ["", ...extensions] })
alt Resolved file path
RMP-->>UM: /abs/path or file: URL
UM->>FS: stat/isFile?
FS-->>UM: is file
UM-->>SB: resolved path
else Error or not file
RMP-->>UM: throws or non-file
UM-->>SB: undefined
end
sequenceDiagram
autonumber
actor TP as Telemetry
participant PJR as getActualPackageJson
participant IMR as import.meta.resolve
TP->>PJR: getActualPackageJson(packageName)
PJR->>IMR: resolve(`${packageName}/package.json`, cwd)
IMR-->>PJR: URL or throws
alt Resolved
PJR-->>TP: package.json content/path (existing logic)
else Fallback
PJR-->>TP: previous fallback behavior (unchanged)
end
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
Comment |
8079102 to
c94db38
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/core/src/telemetry/package-json.ts (1)
36-41: Fix path/URL mixing in fallback to avoid ERR_INVALID_URL_SCHEME (Windows).
import.meta.resolve()returns a file URL; passing that intopathToFileURL()(which expects a filesystem path) double-wraps and can throw on Windows. Convert the fallback result to a path first.- resolvedPackageJsonPath = import.meta.resolve(`${packageName}/package.json`, process.cwd()); + resolvedPackageJsonPath = fileURLToPath( + import.meta.resolve(`${packageName}/package.json`, process.cwd()) + );
🧹 Nitpick comments (4)
code/core/src/telemetry/package-json.ts (1)
32-35: Optional: normalize the parent argument to a URL.Passing
process.cwd()works in practice, but Node’simport.meta.resolveexpects a URL-like parent. UsingpathToFileURL(process.cwd()).hrefis more robust across runtimes.- let resolvedPackageJsonPath = pkg.up({ - cwd: fileURLToPath(import.meta.resolve(packageName, process.cwd())), - }); + let resolvedPackageJsonPath = pkg.up({ + cwd: fileURLToPath(import.meta.resolve(packageName, pathToFileURL(process.cwd()).href)), + });docs/_snippets/storybook-main-pnpm-with-module-resolution.md (1)
26-31: Remove unused import in TS snippet.
joinis no longer used after switching to template literals.-import { dirname, join } from 'node:path'; +import { dirname } from 'node:path';code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath-utils.ts (1)
165-171: Provide cooked values in TemplateElement nodes.
@babel/typesprefers bothrawandcooked. Supplying onlyrawcan trip tooling/print edge cases.- t.templateLiteral( - [ - t.templateElement({ raw: '' }), - t.templateElement({ raw: '/package.json' }, true), - ], - [t.identifier('value')] - ), + t.templateLiteral( + [ + t.templateElement({ raw: '', cooked: '' }), + t.templateElement({ raw: '/package.json', cooked: '/package.json' }, true), + ], + [t.identifier('value')] + ),MIGRATION.md (1)
570-581: Clarify builder path vs file URL in example.
import.meta.resolve()typically returns a file URL; the text/comment shows a filesystem path. To avoid confusion (and to satisfy “fully resolved path”), either convert to a path or update the comment.Option A (path string):
-import { dirname } from 'node:path'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; … - builder: import.meta.resolve('@storybook/builder-vite'), - // 👆 results in eg. `/absolute/path/node_modules/@storybook/builder-vite/index.js + builder: fileURLToPath(import.meta.resolve('@storybook/builder-vite')), + // 👆 results in e.g. `/absolute/path/node_modules/@storybook/builder-vite/index.js`Option B (keep URL): adjust the comment to “file URL”.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
MIGRATION.md(1 hunks)code/core/src/telemetry/package-json.ts(1 hunks)code/lib/cli-storybook/src/automigrate/fixes/__test__/main-config-with-wrappers.js(1 hunks)code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath-utils.ts(2 hunks)code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.test.ts(2 hunks)code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.ts(1 hunks)docs/_snippets/storybook-main-pnpm-with-module-resolution.md(2 hunks)test-storybooks/yarn-pnp/.storybook/main.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- test-storybooks/yarn-pnp/.storybook/main.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (5)
code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath-utils.ts (2)
136-138: Docstring matches implementation.Example now correctly shows the
${value}/package.jsonapproach viaimport.meta.resolve. LGTM.
114-128: Confirm import injection fordirname/fileURLToPath.This util generates a function using
dirnameandfileURLToPath. Ensure the automigration also inserts/imports these fromnode:pathandnode:urlwhen missing.Would you like a script that scans generated configs to verify the imports are present?
code/lib/cli-storybook/src/automigrate/fixes/__test__/main-config-with-wrappers.js (1)
1-6: LGTM: wrapper now resolves via URL → path → dir.Matches the new guidance and is Windows-safe.
code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.test.ts (2)
103-103: LGTM: snapshot now imports onlydirnamefromnode:path.In sync with generator changes.
124-125: Confirm Node >=18.19.0 support and add a Vitest fallback for import.meta.resolveNode unflagged import.meta.resolve starting in v18.19.0, but vite-node/Vitest often don’t implement import.meta.resolve in tests (errors like vite_ssr_import_meta.resolve is not a function). For the code at code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.test.ts (lines 124–125) either ensure CI/local Node is >=18.19.0 or add a test/runtime fallback (stub vite_ssr_import_meta.resolve or use an import-meta-resolve ponyfill) so snapshots don’t break.
| mainConfig.setImport(['dirname'], 'node:path'); | ||
| mainConfig.setImport(['fileURLToPath'], 'node:url'); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
LGTM: drop join import; keep only dirname.
Matches the new import.meta.resolve(\${value}/package.json`)` approach and avoids path-concat pitfalls.
Run to ensure no stale join(value, 'package.json') patterns remain in the repo:
🏁 Script executed:
#!/bin/bash
rg -nP -C2 '\bjoin\s*\(\s*value\s*,\s*["\']package\.json["\']\s*\)'Length of output: 68
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Searching for exact join(value, 'package.json') patterns..."
rg -nP -C2 '\bjoin\s*\(\s*[^,)]*value\s*,\s*[\x27\x22]package\.json[\x27\x22]\s*\)' || echo "No exact matches"
echo
echo "Searching (looser) for lines that contain join(...value...package.json)..."
rg -nP -C2 'join\s*\(.*value.*package\.json' || echo "No looser matches"Length of output: 2143
Fix remaining join(...) usage — replace with import.meta.resolve(${value}/package.json) and drop join import.
Occurrences: code/lib/create-storybook/src/generators/baseGenerator.ts — lines 410 and 417 (calls: return dirname(fileURLToPath(import.meta.resolve(join(value, 'package.json'))))).
Replace join(value, 'package.json') with ${value}/package.json inside import.meta.resolve and remove the join import.
🤖 Prompt for AI Agents
In code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.ts around
lines 75-77 and in code/lib/create-storybook/src/generators/baseGenerator.ts at
lines ~410 and ~417, replace the use of join(value, 'package.json') inside
import.meta.resolve with a template literal `${value}/package.json`, and remove
any import of join from the module; specifically update the two calls that
currently do fileURLToPath(import.meta.resolve(join(value, 'package.json'))) to
use fileURLToPath(import.meta.resolve(`${value}/package.json`)) and delete the
join import and any dead code references.
On windows this will use the incorrect path separator, resulting in unpredictable behaviour
0fe2141 to
696eb54
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
code/lib/create-storybook/src/generators/baseGenerator.ts (2)
399-419: Generated ESM imports: prefernode:specifiers and correct TS return type
- Use
node:-prefixed builtins in generated code to match Node ESM guidance and your docs.- The TS variant should return
string, notany.Apply this diff to the generated prefixes:
- 'import { dirname } from "path"', - 'import { fileURLToPath } from "url"', + 'import { dirname } from "node:path";', + 'import { fileURLToPath } from "node:url";', @@ - function getAbsolutePath(value) { - return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))) + function getAbsolutePath(value) { + return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))); }` : dedent`/** * This function is used to resolve the absolute path of a package. * It is needed in projects that use Yarn PnP or are set up within a monorepo. */ - function getAbsolutePath(value: string): any { - return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))) + function getAbsolutePath(value: string): string { + return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))); }`,
474-481: Resolve internal package root robustlyMinor: this path is resolved at runtime; if resolution ever fails in monorepos, adding a base to
import.meta.resolveavoids edge cases.- commonAssetsDir: join( - dirname(fileURLToPath(import.meta.resolve('create-storybook/package.json'))), + commonAssetsDir: join( + dirname(fileURLToPath(import.meta.resolve('create-storybook/package.json', import.meta.url))), 'rendererAssets', 'common' ),MIGRATION.md (2)
570-574: Doc snippet usesrequire.resolvein ESM: addcreateRequirefor correctnessReaders copying this into ESM will hit “require is not defined.” Show
createRequire.-import { dirname } from 'node:path'; - -const getAbsolutePath = (input) => - dirname(require.resolve(`${input}/package.json`)); +import { dirname } from 'node:path'; +import { createRequire } from 'node:module'; +const require = createRequire(import.meta.url); +const getAbsolutePath = (input) => + dirname(require.resolve(`${input}/package.json`));
579-581: Builder example: clarify URL vs path
import.meta.resolve('@storybook/builder-vite')returns a URL string. Consider adding a short note orfileURLToPathin the example to prevent confusion for consumers expecting a filesystem path.Suggested edit:
- builder: import.meta.resolve('@storybook/builder-vite'), + // Resolve to a file URL, convert to a path if needed: + // builder: fileURLToPath(import.meta.resolve('@storybook/builder-vite')), + builder: import.meta.resolve('@storybook/builder-vite'),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
MIGRATION.md(1 hunks)code/core/src/telemetry/package-json.ts(1 hunks)code/lib/cli-storybook/src/automigrate/fixes/__test__/main-config-with-wrappers.js(1 hunks)code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath-utils.ts(2 hunks)code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.test.ts(2 hunks)code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.ts(1 hunks)code/lib/create-storybook/src/generators/baseGenerator.ts(1 hunks)docs/_snippets/storybook-main-pnpm-with-module-resolution.md(2 hunks)test-storybooks/yarn-pnp/.storybook/main.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- test-storybooks/yarn-pnp/.storybook/main.ts
- code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.test.ts
- code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath.ts
- code/lib/cli-storybook/src/automigrate/fixes/wrap-getAbsolutePath-utils.ts
- code/core/src/telemetry/package-json.ts
- docs/_snippets/storybook-main-pnpm-with-module-resolution.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (1)
code/lib/cli-storybook/src/automigrate/fixes/__test__/main-config-with-wrappers.js (1)
1-1: ESM builtins: keep specifiers consistent and verify Windows behavior
- node: specifiers are fine. Found wrapForPnp usage in code/lib/cli-storybook/src/automigrate/fixes/test/main-config-with-wrappers.js (addons and framework.name). import.meta.resolve can produce file:// URLs with forward slashes on Windows (Node 20.19+); verify on Windows + Yarn PnP that the paths passed to wrapForPnp are normalized/converted (e.g., fileURLToPath or path.normalize) to avoid path-format regressions.
Package BenchmarksCommit: The following packages have significant changes to their size or dependencies:
|
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 124 | 124 | 0 |
| Self size | 4.10 MB | 4.01 MB | 🎉 -81 KB 🎉 |
| Dependency size | 21.62 MB | 21.62 MB | 🚨 +18 B 🚨 |
| Bundle Size Analyzer | Link | Link |
@storybook/sveltekit
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 20 | 20 | 0 |
| Self size | 58 KB | 48 KB | 🎉 -11 KB 🎉 |
| Dependency size | 26.85 MB | 26.85 MB | 🎉 -498 B 🎉 |
| Bundle Size Analyzer | Link | Link |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/frameworks/angular/src/preset.ts (1)
15-28: Avoid mixing file URLs and file paths in annotations
configis a file path, butpreviewProdPathanddocsConfigPathremain file URLs. Normalize all entries to file paths to prevent cross‑platform issues (esp. Windows) and to match other frameworks (see nextjs/sveltekit presets).Apply this diff:
const config = fileURLToPath(import.meta.resolve('@storybook/angular/client/config')); const annotations = [...entries, config]; if ((options as any as StandaloneOptions).enableProdMode) { - const previewProdPath = import.meta.resolve('@storybook/angular/client/preview-prod'); - annotations.unshift(previewProdPath); + const previewProdPath = fileURLToPath( + import.meta.resolve('@storybook/angular/client/preview-prod') + ); + annotations.unshift(previewProdPath); } const docsConfig = await options.presets.apply('docs', {}, options); const docsEnabled = Object.keys(docsConfig).length > 0; if (docsEnabled) { - const docsConfigPath = import.meta.resolve('@storybook/angular/client/docs/config'); - annotations.push(docsConfigPath); + const docsConfigPath = fileURLToPath( + import.meta.resolve('@storybook/angular/client/docs/config') + ); + annotations.push(docsConfigPath); }
🧹 Nitpick comments (1)
code/frameworks/angular/src/preset.ts (1)
36-40: Consider normalizing builder name resolution
import.meta.resolvereturns a file URL. Prefer passing either the package specifier or a file path for consistency with the Windows fix. Verify which form the core expects here.Two safe options (pick one, confirm e2e on Windows/Yarn PnP):
- name: import.meta.resolve('@storybook/builder-webpack5'), + name: '@storybook/builder-webpack5',or
- name: import.meta.resolve('@storybook/builder-webpack5'), + name: fileURLToPath(import.meta.resolve('@storybook/builder-webpack5')),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
code/frameworks/angular/src/preset.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
code/frameworks/angular/src/preset.ts (4)
code/frameworks/react-webpack5/src/preset.ts (1)
addons(9-11)code/frameworks/nextjs/src/preset.ts (2)
addons(19-21)previewAnnotations(50-53)code/frameworks/nextjs-vite/src/preset.ts (1)
previewAnnotations(37-40)code/frameworks/sveltekit/src/preset.ts (1)
previewAnnotations(16-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: normal
- GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (2)
code/frameworks/angular/src/preset.ts (2)
4-4: LGTM: importing fileURLToPath is correct for resolving to absolute pathsThis aligns with the Windows fix strategy.
7-8: LGTM: resolve addon presets to file pathsGood move to absolute file paths via fileURLToPath(import.meta.resolve(...)).
exsolve resolveModulePath for safeResolveModule
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/core/src/common/presets.ts (1)
81-84: Use POSIX-style module specifiers — avoid pathe.join for specifiersjoin(name, 'preset'|'manager'|'preview') can produce platform-specific separators (\ on Windows); replace with POSIX-style
${name}/...and remove the now-unused join import.File: code/core/src/common/presets.ts
- const presetFile = safeResolveModule({ specifier: join(name, 'preset'), parent: configDir }); - const managerFile = safeResolveModule({ specifier: join(name, 'manager'), parent: configDir }); - const previewFile = safeResolveModule({ specifier: join(name, 'preview'), parent: configDir }); + const presetFile = safeResolveModule({ specifier: `${name}/preset`, parent: configDir }); + const managerFile = safeResolveModule({ specifier: `${name}/manager`, parent: configDir }); + const previewFile = safeResolveModule({ specifier: `${name}/preview`, parent: configDir });Also remove the unused join import:
-import { join, parse, resolve } from 'pathe'; +import { parse, resolve } from 'pathe';
🧹 Nitpick comments (1)
code/core/src/common/presets.ts (1)
239-242: Align error logging with stack/message for consistencyMirror the improved logging used above so stack traces are printed reliably here as well.
Apply this diff:
- logger.warn(warning); - logger.error(error); + logger.warn(warning); + const err = error as Error; + logger.error(err.stack ?? err.message);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
code/core/src/common/presets.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: normal
- GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (1)
code/core/src/common/presets.ts (1)
131-133: Useful stack-aware error logging added — LGTMLogging
error.stack ?? error.messagewill make failures much easier to diagnose.
| if (e.code !== 'ERR_MODULE_NOT_FOUND') { | ||
| throw e; | ||
| } |
There was a problem hiding this comment.
This is the cause of the error @mrginglymus
Can you explain why you added this?
There was a problem hiding this comment.
I've removed the code, for now.
There was a problem hiding this comment.
Because the old logic would iterate through extensions it was expected that at least some of them would throw, but that's ok because the throw just said 'move on to the next extension'- they are recoverable exceptions.
However, this was also catching and thus masking the critical error from fileURLToPath (or whichever function was choking on windows absolute paths).
I'd hoped that being a bit more selective in error codes would allow to differentiate between 'the module isn't there, let's just carry on' (ie, the existing behaviour) and 'there's a critical configuration error or bug in storybook that needs fixing'.
Obviously I've missed the target there and we're getting more than just ERR_MODULE_NOT_FOUND on the happy path.
jonniebigodes
left a comment
There was a problem hiding this comment.
@mrginglymus thanks for taking the time to update the documentation. Appreciate it 🙏 ! I've checked and all is good on my end. I'll defer to @ndelangen on this, as he left some items for you to check when you're able.
Have a great day.
Stay safe
getAbsolutePathwrapper incorrect on windows #32485What I did
Use exsolve for
safeResolveModule, as this can handle absolute paths on windows (whichfileURLToPath(import.meta.resolve(...))cannot).This does mean we bypass the
importMetaResolvecheck for vitest...I'm hoping that for this specific use case its ok.The linked issue in that code (vitest-dev/vitest#6953) is now closed for vite 7
I've also updated the yarn pnp sandbox to wrap frameworks and addons in
getAbsolutePath.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
Just running a sandbox on windows should be enough to demonstrate this.
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>Greptile Summary
Updated On: 2025-09-16 12:22:17 UTC
This PR addresses a Windows compatibility issue in Storybook 10.0.0-beta.3 by replacing the module resolution implementation in the
safeResolveModulefunction. The change switches from using Node.js's nativeimport.meta.resolve()combined withfileURLToPath()to theexsolvelibrary'sresolveModulePathfunction.The core problem was that the previous implementation would throw
ERR_INVALID_URL_SCHEMEerrors when handling absolute paths on Windows systems. Theexsolvelibrary provides better cross-platform compatibility and can properly resolve absolute paths on Windows where the native Node.js resolution methods fail.The implementation maintains the same API and functionality while simplifying the code structure. Instead of manually looping through file extensions and using multiple try-catch blocks, the new approach uses
exsolve's built-in extension handling and only re-throws errors that are notERR_MODULE_NOT_FOUND. This change is part of Storybook's module resolution utilities that are used throughout the codebase for finding and loading various components and configuration files.Confidence score: 4/5
code/core/src/shared/utils/module.tsfile to ensure the exsolve integration works correctly across different environmentsSummary by CodeRabbit
Bug Fixes
Refactor
Documentation
Breaking Change